package com.bysj.sausys.service.impl;

import com.bysj.sausys.beans.PageQuery;
import com.bysj.sausys.beans.PageResult;
import com.bysj.sausys.beans.Pagination;
import com.bysj.sausys.beans.SubmitTaskBean;
import com.bysj.sausys.common.AssConst;
import com.bysj.sausys.common.UserConst;
import com.bysj.sausys.common.WorkFlowConst;
import com.bysj.sausys.dao.SysAssActMapper;
import com.bysj.sausys.exception.ParamException;
import com.bysj.sausys.model.SysAssAct;
import com.bysj.sausys.service.ISysAssActService;
import com.bysj.sausys.service.ISysWorkFlowService;
import com.bysj.sausys.util.ObjectUtils;
import com.bysj.sausys.util.PropertiesUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 社团活动申请Service实现
 *
 * @author WangZK
 */
@Service("sysAssActService")
public class SysAssActServiceImpl implements ISysAssActService {

    @Resource
    private SysAssActMapper sysAssActMapper;
    @Resource
    private ISysWorkFlowService sysWorkFlowService;

    /**
     * 保存社团活动申请单
     *
     * @param sysAssAct
     * @param username
     */
    @Override
    public void save(SysAssAct sysAssAct, String username, Integer assId) {
        //判断是否已经存在没有审核完成的社团活动申请单
        if (checkAssActExist(sysAssAct.getId(), assId, sysAssAct.getActName())) {
            throw new ParamException("社团活动申请单已存在，保存申请失败");
        }

        sysAssAct.setAssId(assId);
        sysAssAct.setInsertMan(username);
        sysAssAct.setInsertTime(new Date());
        sysAssActMapper.insertSelective(sysAssAct);
    }

    /**
     * 判断社团活动申请单是否已存在
     *
     * @param id
     * @param assId
     * @param actName
     * @return
     */
    private boolean checkAssActExist(Integer id, Integer assId, String actName) {
        return sysAssActMapper.countByActNameAndAssIdAndAuditNoComp(id, assId, actName) > 0;
    }

    /**
     * 更新社团活动申请单
     *
     * @param sysAssAct
     * @param username
     * @param assId
     */
    @Override
    public void update(SysAssAct sysAssAct, String username, Integer assId) {
        SysAssAct before = sysAssActMapper.selectByPrimaryKey(sysAssAct.getId());
        if (AssConst.NON_EDITABLE.getCode().equals(before.getEditStatus())) {
            throw new ParamException("社团活动申请单为不可编辑状态，编辑失败");
        }
        if (before == null) {
            throw new ParamException("待更新的社团活动申请单不存在");
        }
        if (checkAssActExist(sysAssAct.getId(), assId, sysAssAct.getActName())) {
            throw new ParamException("社团活动申请已存在，保存申请失败");
        }

        SysAssAct after = new SysAssAct();

        after.setId(sysAssAct.getId());
        after.setHostUnit(sysAssAct.getHostUnit());
        after.setCoUnit(sysAssAct.getCoUnit());
        after.setAssId(assId);
        after.setActName(sysAssAct.getActName());
        after.setActTime(sysAssAct.getActTime());
        after.setActZone(sysAssAct.getActZone());
        after.setActPlace(sysAssAct.getActPlace());
        after.setActType(sysAssAct.getActType());
        after.setActNumber(sysAssAct.getActNumber());
        after.setActLead(sysAssAct.getActLead());
        after.setActLeadTeacher(sysAssAct.getActLeadTeacher());
        after.setActRemarks(sysAssAct.getActRemarks());
        after.setActPlan(sysAssAct.getActPlan());
        after.setLastupdMan(username);
        after.setLastupdTime(new Date());
        sysAssActMapper.updateByPrimaryKeySelective(after);
    }

    /**
     * 根据id获取社团活动申请单
     *
     * @param id
     * @return
     */
    @Override
    public SysAssAct findById(Integer id) {
        return sysAssActMapper.selectByPrimaryKey(id);
    }

    /**
     * 分页获取社团活动申请单
     *
     * @param pageQuery
     * @param map
     * @return
     */
    @Override
    public PageResult<SysAssAct> getPage(PageQuery pageQuery, Map map) {
        Integer assId = UserConst.getCurrentAssId(map);
        if (assId == -1) {
            return getPageForAuditComp(pageQuery);
        } else {
            return getPageByAssId(pageQuery, assId);
        }
    }

    /**
     * 分页获取审批完成的社团活动申请列表
     *
     * @param pageQuery
     * @return
     */
    private PageResult<SysAssAct> getPageForAuditComp(PageQuery pageQuery) {
        int count = sysAssActMapper.countByAuditStatus(AssConst.ASS_ACT_AUDIT_PASS.getCode());
        if (count > 0) {
            List<SysAssAct> sysAssActList = sysAssActMapper.selectByAuditStatus(AssConst.ASS_ACT_AUDIT_PASS.getCode(), pageQuery);
            PageResult result = new PageResult();
            result.setList(sysAssActList);
            Pagination pagination = new Pagination();
            pagination.setTotal(count);
            pagination.setPageSize(pageQuery.getPageSize());
            pagination.setCurrentPage(pageQuery.getPageNo());
            result.setPagination(pagination);
            return result;
        }
        return new PageResult<>();
    }

    /**
     * 根据社团id分页获取社团活动申请列表
     */
    private PageResult<SysAssAct> getPageByAssId(PageQuery pageQuery, Integer assId) {
        int count = sysAssActMapper.countByAssId(assId);
        if (count > 0) {
            List<SysAssAct> sysAssActList = sysAssActMapper.getPageByAssId(pageQuery, assId);
            PageResult<SysAssAct> result = new PageResult<>();
            result.setList(sysAssActList);
            Pagination pagination = new Pagination();
            pagination.setTotal(count);
            pagination.setPageSize(pageQuery.getPageSize());
            pagination.setCurrentPage(pageQuery.getPageNo());
            result.setPagination(pagination);
            return result;
        }
        return new PageResult<>();
    }

    /**
     * 根据id删除社团活动申请单
     *
     * @param id
     */
    @Override
    public void delete(Integer id) {
        SysAssAct sysAssAct = sysAssActMapper.selectByPrimaryKey(id);
        if (sysAssAct == null) {
            throw new ParamException("社团活动申请单不存在，删除失败");
        }
        if (AssConst.NON_DELETING.getCode().equals(sysAssAct.getDeleteStatus())) {
            throw new ParamException("社团活动申请单为不可删除状态，删除失败");
        }
        sysAssActMapper.deleteByPrimaryKey(id);
    }

    /**
     * 启动社团活动申请审批流程
     *
     * @param id
     * @param username
     */
    @Override
    public void saveStartProcess(Integer id, String username) {
        SysAssAct sysAssAct = sysAssActMapper.selectByPrimaryKey(id);
        if (sysAssAct == null) {
            throw new ParamException("社团活动申请单不存在，启动流程失败");
        }
        if (!AssConst.ASS_ACT_INIT_ENTRY.getCode().equals(sysAssAct.getAuditStatus())) {
            throw new ParamException("流程已启动，不需要再次启动");
        }

        //调用工作流的service，执行启动流程实例，让启动的流程实例关联业务的操作
        //1.通过配置文件获取流程定义的key
        String key = PropertiesUtil.getProperty(WorkFlowConst.ASS_ACT_KEY.getCode());
        //2.设置字符串
        String objId = sysAssAct.getClass().getSimpleName() + "." + id;

        String processInstanceId = sysWorkFlowService.saveStartProcess(key, objId, username);

        if (processInstanceId == null || "".equals(processInstanceId)) {
            throw new ParamException("启动社团活动申请审批流程失败");
        }

        //更改推文的状态
        Map map = new HashMap(4);
        map.put("id", id);
        map.put("deleteStatus", AssConst.NON_DELETING.getCode());
        map.put("editStatus", AssConst.NON_EDITABLE.getCode());
        map.put("auditStatus", AssConst.ASS_ACT_AUDITING.getCode());
        sysAssActMapper.updateStatus(map);
    }

    /**
     * 获取审批信息
     *
     * @param taskId
     * @return
     */
    @Override
    public Map getAuditInfo(String taskId) {
        // 获取连线信息和历史审核人信息
        Map<String, Object> map = sysWorkFlowService.getAuditInfo(taskId);

        /**
         * 获取业务数据
         * 1.获取数据id
         * 2.根据id获取业务数据
         */
        int id = sysWorkFlowService.getBusinessIdByTaskId(taskId);
        SysAssAct sysAssAct = sysAssActMapper.selectByPrimaryKey(id);
        if (sysAssAct == null) {
            throw new ParamException("获取社团活动申请单失败");
        }
        try {
            Map objectMap = ObjectUtils.objectToMap(sysAssAct);
            objectMap.remove("insertTime");
            objectMap.remove("insertMan");
            objectMap.remove("lastupdTime");
            objectMap.remove("lastupdMan");

            map.put("businessData", objectMap);
            map.put("taskId", taskId);

            return map;
        } catch (IllegalAccessException e) {
            throw new ParamException("获取社团活动申请单失败");
        }
    }

    /**
     * 提交任务
     *
     * @param submitTaskBean
     * @param username
     */
    @Override
    public void saveSubmitTask(SubmitTaskBean submitTaskBean, String username) {
        Map variables = new HashMap(4);
        SysAssAct sysAssAct = sysAssActMapper.selectByPrimaryKey(submitTaskBean.getId());
        variables.put("actNumber", sysAssAct.getActNumber());
        variables.put("actZone", sysAssAct.getActZone());
        //调用工作流封装好的方法
        String processInstanceId = sysWorkFlowService.saveSubmitTask(submitTaskBean, username, variables);

        //判断是否需要更改申请表状态
        if (sysWorkFlowService.checkProcessIsEnd(processInstanceId)) {
            Map map = new HashMap(4);
            map.put("id", submitTaskBean.getId());
            map.put("deleteStatus", AssConst.DELETING.getCode());
            map.put("editStatus", AssConst.NON_EDITABLE.getCode());
            sysAssActMapper.updateStatus(map);
        }
    }

    /**
     * 获取历史的审批信息
     *
     * @param id
     * @return
     */
    @Override
    public Map getHisComment(Integer id) {
        SysAssAct sysAssAct = sysAssActMapper.selectByPrimaryKey(id);
        String objId = sysAssAct.getClass().getSimpleName() + "." + id;

        Map<String, Object> map = sysWorkFlowService.findCommentByObjId(objId);
        map.put("businessData", sysAssAct);
        return map;
    }

    /**
     * 修改社团活动申请单的状态
     *
     * @param map
     */
    @Override
    public void updateStatus(Map map) {
        sysAssActMapper.updateStatus(map);
    }
}
